package HTTP;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

public class HttpClientTutorial {

	/**
	 * En caso de salir a Internet a tavés de un Proxy, se deberán modificar los
	 * siguientes parámetros
	 */
	public static final boolean byProxy = false;
	public static final String ProxyAddress = "TuProxyAddress";
	public static final int ProxyPort = 1234;

	/**
	 * Direcciones que usamos para enviar peticiones
	 */
	public static final String TargetURLSSL = "https://www.verisign.com";
	public static final String TargetURL = "http://www.autentia.es";

	/**
	 * Por defecto haremos una petición HTTP GET. Cambiar a false para
	 * peticiones HTTP POST
	 */
	public static final boolean ByGet = true;

	/**
	 * Si queremos hacer conectarnos a un servidor seguro via SSL poner a true
	 * la siguiente variable
	 */
	public static final boolean BySSL = false;

	/**
	 * En caso de necesitar autentificacion con el servidor modificar los
	 * siguientes parámetros
	 */
	public static final boolean Authenticate = false;
	public static final String UsernameCredentials = "TuUsuario";
	public static final String PasswordCredentials = "TuPassword";

	/**
	 * Punto de inicio de ejecución del ejemplo.
	 */
	public static void main(String[] args) {
		
		HttpClient httpClient = null; // Objeto a través del cual realizamos las peticiones
		HttpMethodBase request = null; // Objeto para realizar las peticiones HTTP GET o POST
		int status = 0; // Código de la respuesta HTTP
		BufferedReader reader = null; // Se usa para leer la respuesta a la petición
		String line = null; // Se usa para leer cada una de las lineas de texto de la respuesta

		// Instanciamos el objeto
		httpClient = new HttpClient();

		// Especificamos que salimos a través de un Proxy.
		if (byProxy) {
			httpClient.getHostConfiguration().setProxy(
					HttpClientTutorial.ProxyAddress,
					HttpClientTutorial.ProxyPort );
		}

		if (ByGet) {
			// Invocamos por GET

			// ¿ Nos conectamos a un servidor seguro ?
			// Observe que si están bien instalado JSSE (Java Secure Socket
			// Extension),
			// el código es exactamente igual
			if (BySSL) {
				request = new GetMethod(HttpClientTutorial.TargetURLSSL);
			} else {
				request = new GetMethod(HttpClientTutorial.TargetURL);
			}

			// Le indicamos que realize automáticamente el seguimiento de las
			// redirecciones
			// en caso de que existan.
			request.setFollowRedirects(true);

			// Añadimos los parámetros que deseemos a la petición
			// GET: http://dominio/pagina?nombre=Carlos+Garc%C3%ADa
			NameValuePair params[] = { new NameValuePair("nombre", "Carlos García") };
			request.setQueryString(params);
		} else {
			// Invocamos por POST
			request = new PostMethod(HttpClientTutorial.TargetURL);

			// Añadimos los parámetros que deseemos a la petición
			((PostMethod) request).addParameter("nombre", "Carlos García");
		}

		try {
			// Si su servidor requiere autentificación necesitará una línea como
			// la siguiente
			if (Authenticate) {
				UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(
						UsernameCredentials, PasswordCredentials);
				httpClient.getState().setCredentials(
						new AuthScope(request.getURI().getHost(), 80,
								AuthScope.ANY_REALM), credentials);

				// Indicamos que se autentifique si fuese requerido
				request.setDoAuthentication(true);
			}

			// Indicamos reintente 3 veces en caso de que haya errores.
			request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
					new DefaultHttpMethodRetryHandler(3, true));

			// Añadimos las cabeceras personalizadas que se requieran, de la
			// siguiente forma:
			request.addRequestHeader("HeadKey", "HeadValue");

			// Enviamos una cookie personalizada a las que el CookieManager ya
			// tenga
			httpClient.getState().addCookie(
					new Cookie(request.getURI().getHost(), "nombreCookie",
							"valorCookie", "/", 3600, false));

			// Leemos el código de la respuesta HTTP que nos devuelve el
			// servidor
			status = httpClient.executeMethod(request);

			// Vemos si la petición se ha realizado satisfactoriamente
			if (status != HttpStatus.SC_OK) {
				System.err.println("Error\t" + request.getStatusCode() + "\t"
						+ request.getStatusText() + "\t"
						+ request.getStatusLine());
			} else {
				// Leemos el contenido de la respuesta y realizamos el
				// tratamiento de la misma.
				// En nuestro caso, simplemente mostramos el resultado por la
				// salida estándar
				reader = new BufferedReader(new InputStreamReader(request
						.getResponseBodyAsStream(), request
						.getResponseCharSet()));
				line = reader.readLine();
				while (line != null) {
					System.out.println(line);
					line = reader.readLine();
				}
			}
		} catch (Exception ex) {
			System.err.println("Error\t: " + ex.getMessage());

			ex.printStackTrace();
		} finally {
			// Liberamos la conexión. (También libera los stream asociados)
			request.releaseConnection();
		}
	}
}
